package com.youkeda.redpacket.api;

import com.youkeda.redpacket.model.*;
import com.youkeda.redpacket.params.PreSingleRedEnvelopeQueryParam;
import com.youkeda.redpacket.params.UserInfoQueryParam;
import com.youkeda.redpacket.params.UserRedEnvelopeRecordQueryParam;
import com.youkeda.redpacket.service.PreSingleRedEnvelopeService;
import com.youkeda.redpacket.service.RedEnvelopeService;
import com.youkeda.redpacket.service.UserRedEnvelopeRecordService;
import com.youkeda.redpacket.service.UserService;
import com.youkeda.redpacket.util.UUIDUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import sun.rmi.runtime.Log;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author 刘正星
 * @version 1.0.0
 * @ClassName UserRedEnvelopeRecordApi.java
 * @Description TODO
 * @createTime 2020年09月29日 15:14:00
 */
@RestController
@RequestMapping("/api")
public class UserRedEnvelopeRecordApi {
    @Autowired
    private UserRedEnvelopeRecordService userRedEnvelopeRecordService;
    @Autowired
    private RedEnvelopeService redEnvelopeService;
    @Autowired
    private PreSingleRedEnvelopeService preSingleRedEnvelopeService;
    @Autowired
    private UserService userService;
    @Autowired
    private RedissonClient redissonClient;

    @GetMapping("/dismantle")
    public Result<UserRedEnvelopeRecord> dismantle(@RequestParam(value = "userId", required = false) String userId, @RequestParam(value = "redEnvelopeId") String redEnvelopeId) {
        Result result = new Result();
        result.setSuccess(true);
        if (StringUtils.isEmpty(redEnvelopeId)) {
            result.setSuccess(false);
            return result;
        }

        if (StringUtils.isEmpty(userId)) {
            result.setSuccess(false);
            return result;
        }
        PreSingleRedEnvelopeQueryParam param = new PreSingleRedEnvelopeQueryParam();
        param.setRedEnvelopeId(redEnvelopeId);
        //是否有红包剩余
        List<PreSingleRedEnvelope> preSingleRedEnvelopes = preSingleRedEnvelopeService.query(param).stream()
                .filter(preSingleRedEnvelope -> preSingleRedEnvelope.getStatus().equals(PreSingleRedEnvelopeStatus.TODO))
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(preSingleRedEnvelopes)) {
            result.setSuccess(false);
            result.setMessage("红包已领取完，手速慢了~");
            return result;
        }
        //是否同一个人领取
        UserRedEnvelopeRecordQueryParam userRedEnvelopeRecordQueryParam = new UserRedEnvelopeRecordQueryParam();
        userRedEnvelopeRecordQueryParam.setUserId(userId);
        userRedEnvelopeRecordQueryParam.setRedEnvelopeId(redEnvelopeId);
        List<UserRedEnvelopeRecord> userRedEnvelopeRecords = userRedEnvelopeRecordService.query(userRedEnvelopeRecordQueryParam);
        //领取记录不为空
        if (!CollectionUtils.isEmpty(userRedEnvelopeRecords)) {
            result.setSuccess(false);
            result.setMessage("已经领取过！");
            return result;
        }
        //随机一个红包
        RLock rLock = redissonClient.getLock("RED_ENVELOPE");
        try {
            boolean unlock = rLock.tryLock(3, 10, TimeUnit.SECONDS);
            if (unlock) {
                //拆红包
                Random random = new Random();
                int randomRed = random.nextInt(preSingleRedEnvelopes.size());
                PreSingleRedEnvelope preSingleRedEnvelope = preSingleRedEnvelopes.get(randomRed);
                preSingleRedEnvelope.setStatus(PreSingleRedEnvelopeStatus.DONE);
                //实例一个领取记录
                UserRedEnvelopeRecord userRedEnvelopeRecord = new UserRedEnvelopeRecord();
                userRedEnvelopeRecord.setId(UUIDUtils.getUUID());
                userRedEnvelopeRecord.setUserId(userId);
                userRedEnvelopeRecord.setRedEnvelopeId(redEnvelopeId);
                userRedEnvelopeRecord.setPreSingleRedEnvelopeId(preSingleRedEnvelope.getId());
                //插入用户领取记录
                UserRedEnvelopeRecord InsertRecord = userRedEnvelopeRecordService.save(userRedEnvelopeRecord);
                //更新红包领取状态
                PreSingleRedEnvelope preSingleRedEnvelopeUpdate = preSingleRedEnvelopeService.save(preSingleRedEnvelope);
                if (InsertRecord == null || preSingleRedEnvelopeUpdate == null) {
                    result.setSuccess(false);
                    result.setMessage("插入失败/更新失败！");
                }

                result.setData(InsertRecord);
                result.setMessage("领取成功");
            }

        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return result;
    }

    @GetMapping("/query")
    public Result<List<UserRedEnvelopeRecord>> query(@RequestParam("redEnvelopeId") String redEnvelopeId) {
        Result result = new Result();
        result.setSuccess(true);
        if (StringUtils.isEmpty(redEnvelopeId)) {
            result.setSuccess(false);
            result.setMessage("redEnvelope 为空");
            return result;
        }
        UserRedEnvelopeRecordQueryParam param = new UserRedEnvelopeRecordQueryParam();
        param.setRedEnvelopeId(redEnvelopeId);
        List<UserRedEnvelopeRecord> userRedEnvelopeRecords = userRedEnvelopeRecordService.query(param);
        if (CollectionUtils.isEmpty(userRedEnvelopeRecords)) {
            result.setSuccess(false);
            result.setMessage("无用户记录");
            return result;
        }
        //这里可以转到Service层
        UserInfoQueryParam userInfoQueryParam = new UserInfoQueryParam();
        List<String> ids = new ArrayList<>();
        userRedEnvelopeRecords.forEach(userRedEnvelopeRecord -> {
            ids.add(userRedEnvelopeRecord.getId());
        });
        userInfoQueryParam.setIds(ids);
        List<User> users = userService.query(userInfoQueryParam);
        userRedEnvelopeRecords.forEach(userRedEnvelopeRecord -> {
            users.forEach(user -> {
                if (user.getId().equals(userRedEnvelopeRecord.getId())) {
                    userRedEnvelopeRecord.setUser(user);
                }
            });
        });
        result.setData(userRedEnvelopeRecords);
        return result;
    }
}
